//! WebSocket流管理
//! 
//! 提供WebSocket流的订阅和管理功能

use crate::errors::Result;
use std::collections::HashMap;

/// WebSocket流类型
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum StreamType {
    /// 实时价格
    Ticker,
    /// 订单簿
    Depth,
    /// K线数据
    Kline,
    /// 交易流
    Trade,
    /// 用户数据流
    UserData,
    /// 组合流
    Combined,
}

/// 流配置
#[derive(Debug, Clone)]
pub struct StreamConfig {
    pub stream_type: StreamType,
    pub symbol: String,
    pub interval: Option<String>,
    pub levels: Option<u32>,
    pub listen_key: Option<String>,
}

impl StreamConfig {
    /// 创建实时价格流配置
    pub fn ticker(symbol: &str) -> Self {
        Self {
            stream_type: StreamType::Ticker,
            symbol: symbol.to_string(),
            interval: None,
            levels: None,
            listen_key: None,
        }
    }

    /// 创建订单簿流配置
    pub fn depth(symbol: &str, levels: u32) -> Self {
        Self {
            stream_type: StreamType::Depth,
            symbol: symbol.to_string(),
            interval: None,
            levels: Some(levels),
            listen_key: None,
        }
    }

    /// 创建K线流配置
    pub fn kline(symbol: &str, interval: &str) -> Self {
        Self {
            stream_type: StreamType::Kline,
            symbol: symbol.to_string(),
            interval: Some(interval.to_string()),
            levels: None,
            listen_key: None,
        }
    }

    /// 创建交易流配置
    pub fn trade(symbol: &str) -> Self {
        Self {
            stream_type: StreamType::Trade,
            symbol: symbol.to_string(),
            interval: None,
            levels: None,
            listen_key: None,
        }
    }

    /// 创建用户数据流配置
    pub fn user_data(listen_key: &str) -> Self {
        Self {
            stream_type: StreamType::UserData,
            symbol: String::new(),
            interval: None,
            levels: None,
            listen_key: Some(listen_key.to_string()),
        }
    }
}

/// 流管理器
pub struct StreamManager {
    streams: HashMap<String, StreamConfig>,
}

impl StreamManager {
    /// 创建新的流管理器
    pub fn new() -> Self {
        Self {
            streams: HashMap::new(),
        }
    }

    /// 添加流
    pub fn add_stream(&mut self, config: StreamConfig) -> String {
        let stream_name = self.generate_stream_name(&config);
        self.streams.insert(stream_name.clone(), config);
        stream_name
    }

    /// 移除流
    pub fn remove_stream(&mut self, stream_name: &str) -> Option<StreamConfig> {
        self.streams.remove(stream_name)
    }

    /// 获取所有流
    pub fn get_all_streams(&self) -> Vec<String> {
        self.streams.keys().cloned().collect()
    }

    /// 获取流配置
    pub fn get_stream_config(&self, stream_name: &str) -> Option<&StreamConfig> {
        self.streams.get(stream_name)
    }

    /// 生成流名称
    fn generate_stream_name(&self, config: &StreamConfig) -> String {
        match config.stream_type {
            StreamType::Ticker => format!("{}@ticker", config.symbol.to_lowercase()),
            StreamType::Depth => {
                let levels = config.levels.unwrap_or(20);
                format!("{}@depth{}", config.symbol.to_lowercase(), levels)
            }
            StreamType::Kline => {
                let default_interval = "1m".to_string();
                let interval = config.interval.as_ref().unwrap_or(&default_interval);
                format!("{}@kline_{}", config.symbol.to_lowercase(), interval)
            }
            StreamType::Trade => format!("{}@trade", config.symbol.to_lowercase()),
            StreamType::UserData => {
                config.listen_key.as_ref().unwrap_or(&"".to_string()).clone()
            }
            StreamType::Combined => format!("{}@combined", config.symbol.to_lowercase()),
        }
    }
}

impl Default for StreamManager {
    fn default() -> Self {
        Self::new()
    }
}

/// 流构建器
pub struct StreamBuilder {
    config: StreamConfig,
}

impl StreamBuilder {
    /// 创建新的流构建器
    pub fn new(stream_type: StreamType, symbol: &str) -> Self {
        Self {
            config: StreamConfig {
                stream_type,
                symbol: symbol.to_string(),
                interval: None,
                levels: None,
                listen_key: None,
            },
        }
    }

    /// 设置间隔
    pub fn interval(mut self, interval: &str) -> Self {
        self.config.interval = Some(interval.to_string());
        self
    }

    /// 设置级别
    pub fn levels(mut self, levels: u32) -> Self {
        self.config.levels = Some(levels);
        self
    }

    /// 设置监听密钥
    pub fn listen_key(mut self, listen_key: &str) -> Self {
        self.config.listen_key = Some(listen_key.to_string());
        self
    }

    /// 构建流配置
    pub fn build(self) -> StreamConfig {
        self.config
    }
}

/// 流工具函数
pub struct StreamUtils;

impl StreamUtils {
    /// 构建组合流URL
    pub fn build_combined_stream_url(streams: &[String]) -> String {
        streams.join("/")
    }

    /// 解析流名称
    pub fn parse_stream_name(stream_name: &str) -> Result<StreamConfig> {
        let parts: Vec<&str> = stream_name.split('@').collect();
        if parts.len() != 2 {
            return Err(crate::errors::BinanceError::ParseError(
                "Invalid stream name format".to_string(),
            ));
        }

        let symbol = parts[0].to_string();
        let stream_type = parts[1];

        let config = match stream_type {
            "ticker" => StreamConfig::ticker(&symbol),
            "depth" => StreamConfig::depth(&symbol, 20),
            "kline_1m" => StreamConfig::kline(&symbol, "1m"),
            "kline_3m" => StreamConfig::kline(&symbol, "3m"),
            "kline_5m" => StreamConfig::kline(&symbol, "5m"),
            "kline_15m" => StreamConfig::kline(&symbol, "15m"),
            "kline_30m" => StreamConfig::kline(&symbol, "30m"),
            "kline_1h" => StreamConfig::kline(&symbol, "1h"),
            "kline_2h" => StreamConfig::kline(&symbol, "2h"),
            "kline_4h" => StreamConfig::kline(&symbol, "4h"),
            "kline_6h" => StreamConfig::kline(&symbol, "6h"),
            "kline_8h" => StreamConfig::kline(&symbol, "8h"),
            "kline_12h" => StreamConfig::kline(&symbol, "12h"),
            "kline_1d" => StreamConfig::kline(&symbol, "1d"),
            "kline_3d" => StreamConfig::kline(&symbol, "3d"),
            "kline_1w" => StreamConfig::kline(&symbol, "1w"),
            "kline_1M" => StreamConfig::kline(&symbol, "1M"),
            "trade" => StreamConfig::trade(&symbol),
            _ => {
                return Err(crate::errors::BinanceError::ParseError(
                    format!("Unknown stream type: {}", stream_type),
                ));
            }
        };

        Ok(config)
    }

    /// 验证流名称
    pub fn validate_stream_name(stream_name: &str) -> bool {
        Self::parse_stream_name(stream_name).is_ok()
    }
}
